package com.bootdo.lgs.lgsInterfaces.jzy;

//import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.bootdo.common.model.BdConstant;
import com.bootdo.lgs.lgsInterfaces.jzy.dto.TraceData;
import com.bootdo.lgs.lgsInterfaces.jzy.proxy.LogisticsService;
import com.bootdo.lgs.lgsInterfaces.jzy.proxy.LogisticsServiceSoap;
import com.bootdo.lgs.order.model.LgsOrder;
import com.bootdo.lgs.orderbind.model.OrderBindUpdate;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.xml.ws.WebServiceException;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;

//@Profile(value = {"pro"})
@Component
public class JzyLogisticsService {

    public static String apiJzyLoginName;
    public static String apiJzyLoginPassword;

    private static RedisTemplate redisTemplateStatic;
    @Autowired
    private RedisTemplate redisTemplate;

    private static final Logger logger = LoggerFactory.getLogger(JzyLogisticsService.class);

    private static LogisticsService service = new LogisticsService();
    private static LogisticsServiceSoap soap;

    public JzyLogisticsService() {
    }

    @PostConstruct //@PostConstruct修饰的方法会在服务器加载Servle的时候运行，并且只会被服务器执行一次。PostConstruct在构造函数之后执行,init()方法之前执行
    public void init() {
        redisTemplateStatic = redisTemplate;
    }

    public static Map<String, List<TraceData>> batchQueryTraceData(LoginInfo loginInfo, List<String> traceNumbers) {
        Map<String, List<TraceData>> map = new HashMap();
        if (CollectionUtils.isEmpty(traceNumbers)) {
            return map;
        } else {
            Iterator var3 = traceNumbers.iterator();

            while(var3.hasNext()) {
                String traceNumber = (String)var3.next();
                map.put(traceNumber, getTraceDataByLogisticsNumber(loginInfo, traceNumber));
            }

            return map;
        }
    }

    public static List<TraceData> getTraceDataByLogisticsNumber(LoginInfo loginInfo, String logisticsNumber) {
        ArrayList tdList = new ArrayList();

        String msg = null;
        try {
            logger.info("查询今朝阳物流信息接口单号："+logisticsNumber);
            msg = soap.jGetTraceData(loginInfo.getSessionId(), loginInfo.getUserId(), "JinZhaoYang.Web.Customer", logisticsNumber);
            logger.info("查询今朝阳物流信息接口返回："+msg);
            if (StringUtils.isEmpty(msg))
                return tdList;
        } catch (Exception var9) {
            System.out.println("getTraceDataByLogisticsNumber service is not available! 今朝阳服务接口调用出错!" + var9.getMessage());
            var9.printStackTrace();
        }
        try {
            JSONObject traceData = new JSONObject(msg);
            JSONArray jsonArray = traceData.getJSONArray("ReturnList");

            for(int i = 0; i < jsonArray.length(); ++i) {
                JSONObject o = (JSONObject)jsonArray.get(i);
                TraceData td = new TraceData();
                td.setDocId(o.getLong("DocId"));
                td.setDocNumber(o.getString("DocNumber"));
                td.setStatus(o.getString("Status"));
                td.setStatusComment(o.getString("StatusComment"));
                td.setTraceTime(o.getString("TraceTime"));
                tdList.add(td);
            }
        } catch (JSONException e) {
            //解析失败，很可能登陆失败、输出异常
            try {
                logger.info("物流运单号："+logisticsNumber+"解析查询返回结果失败，msg："+msg,e);
                JSONObject resultData = new JSONObject(msg);
                analyErrorResult(resultData); //停止刷新登陆缓存
            } catch (JSONException ex) {
                ex.printStackTrace();
            }
        }
        return tdList;
    }

    private static LoginInfo analyErrorResult(JSONObject resultData) throws JSONException {
        Long returnCode = resultData.getLong("ReturnCode");
        if(returnCode==-1){
            String errorDescription = resultData.getString("ErrorDescription");
            String message = resultData.getString("Message");
            logger.info("解析失败返回结果，msg："+message+",errorInfo:"+errorDescription);
            logger.info("刷新登陆信息");
            return refreshLoginInfo();
        }
        return null;
    }

    public static List<TraceData> getTraceDataByLogisticsNumber(String logisticsNumber) {
        ArrayList tdList = new ArrayList();

        try {
            LoginInfo loginInfo = login();
            String msg = soap.jGetTraceData(loginInfo.getSessionId(), loginInfo.getUserId(), "JinZhaoYang.Web.Customer", logisticsNumber);
            System.out.println(msg);
            if (StringUtils.isEmpty(msg)) {
                ;
            }

            JSONObject traceData = new JSONObject(msg);
            JSONArray jsonArray = traceData.getJSONArray("ReturnList");

            for(int i = 0; i < jsonArray.length(); ++i) {
                JSONObject o = (JSONObject)jsonArray.get(i);
                TraceData td = new TraceData();
                td.setDocId(o.getLong("DocId"));
                td.setDocNumber(o.getString("DocNumber"));
                td.setStatus(o.getString("Status"));
                td.setStatusComment(o.getString("StatusComment"));
                td.setTraceTime(o.getString("TraceTime"));
                tdList.add(td);
            }
        } catch (Exception var9) {
            System.out.println("getTraceDataByLogisticsNumber service is not available! 今朝阳服务接口调用出错!" + var9.getMessage());
            var9.printStackTrace();
        }

        return tdList;
    }

    public static LoginInfo login(){
        //先到缓存中获取
        String value = null;
        try {
            value = redisTemplateStatic.opsForValue().get(BdConstant.LGS_JZY_LOGIN_INFO).toString();
        } catch (Exception e) {
            logger.warn("从缓存中获取今朝阳登陆信息失败。",e);
        }
        if (StringUtils.isNotBlank(value)){//缓存中存在 从redis缓存中取数据
            System.out.println("从缓存获取登陆信息："+value);
            return JSON.parseObject(value, new TypeReference<LoginInfo>() {});
        }
        return refreshLoginInfo();
    }

    public static LoginInfo refreshLoginInfo(){
        LoginInfo loginInfo = null;
        try {
            loginInfo = loginFromApi();
        } catch (Exception e) {
            logger.warn("调用今朝阳登陆信息接口失败:",e);
        }
        if(loginInfo==null){
            logger.warn("JZY login service is not available! 今朝阳服务接口调用出错! 返回结果为空");
            return new LoginInfo();
        }
        // 将查询到的数据添加到 redis 缓存中
        String loginInfoStr = com.alibaba.fastjson.JSONArray.toJSONString(loginInfo);
        if (StringUtils.isNotBlank(loginInfoStr)){ // loginInfoStr 不为空才放入redis中
            try {
                redisTemplateStatic.opsForValue().set(BdConstant.LGS_JZY_LOGIN_INFO,loginInfoStr,24, TimeUnit.HOURS);
            } catch (Exception e) {
                logger.warn("保存今朝阳登陆信息接口到redis失败:"+loginInfoStr,e);
            }
        }
        logger.info("保存今朝阳登陆信息接口到redis成功:"+loginInfoStr);
        return loginInfo;
    }

    public static LoginInfo loginFromApi() throws JSONException {
        LoginInfo loginInfo = new LoginInfo();
        String result = soap.jLogin(apiJzyLoginName, apiJzyLoginPassword, "JinZhaoYang.Web.Customer", "1.0");
        if (StringUtils.isEmpty(result)) {
            throw new WebServiceException("JZY login service is not available! 今朝阳服务接口调用出错! 返回结果为空");
        } else {
            System.out.println("今朝阳登陆接口返回："+result);
            JSONObject jsonMsg = new JSONObject(result);
            JSONObject loginInfoObject = jsonMsg.getJSONObject("LoginInfo");
            String sessionId = (String)loginInfoObject.get("SessionId");
            int userId = (Integer)loginInfoObject.get("UserId");
            loginInfo.setUserId(userId);
            loginInfo.setSessionId(sessionId);
            return loginInfo;
        }
    }

    public static String getDetailByNumber(String number)throws JSONException{
        LoginInfo loginInfo = login();
        String result = soap.jGetDocumentsByNumber(loginInfo.getSessionId(),loginInfo.getUserId(),loginInfo.clientName,number);
        if (StringUtils.isEmpty(result)) {
            throw new WebServiceException("JZY login service is not available! 今朝阳服务接口调用出错! 返回结果为空");
        } else {
            return result;
        }
    }

    public static List<OrderBindUpdate> saveOrders(List<LgsOrder> lgsOrders) throws Exception {
        long startTime = System.currentTimeMillis();
        List<OrderBindUpdate> result = new ArrayList<>();
        if(lgsOrders==null||lgsOrders.size()<1)
            return result;
        LoginInfo loginInfo = login();
        for(LgsOrder lgsOrder:lgsOrders){
            try {
                OrderBindUpdate orderBindUpdate = save(loginInfo, lgsOrder);
                if (orderBindUpdate != null&&orderBindUpdate.getId()!=null)
                    result.add(orderBindUpdate);
            } catch (Exception e) {
                logger.warn("下单失败:" + lgsOrder, e);
            }
        }
        logger.info("批量下单到今朝阳耗时 : " + (System.currentTimeMillis() - startTime));
        return result;
    }

    public static OrderBindUpdate save(LoginInfo loginInfo,LgsOrder lgsOrder)throws Exception {
        OrderBindUpdate orderBindUpdate  = new OrderBindUpdate();
        lgsOrder.setTransport_mode_nm("快件");

//        lgsOrder.setConsignee("雄帝科技测试");
//        lgsOrder.setConsignee_address("雄帝科技测试");
//        lgsOrder.setConsignee_phone("13511112222");
//        lgsOrder.setGoods_name("雄帝科技测试");
//        lgsOrder.setValue_statement("100");
//        lgsOrder.setDelivery_qty("1");
//        lgsOrder.setProduct_size("11*11*12");

        int cargoValue =getStrToInt(lgsOrder.getValue_statement());
        int packageP = getStrToInt((lgsOrder.getDelivery_qty()));

        BigDecimal bigDecimal = new BigDecimal("0.01");
        String result = jSaveDocument(loginInfo,lgsOrder,cargoValue,packageP,bigDecimal);
        logger.info("登陆信息："+loginInfo+",clientName:"+loginInfo.clientName);
        logger.info("下单内容："+lgsOrder);
        JSONObject resultData = new JSONObject(result);
        logger.info("今朝阳下单接口，返回结果："+resultData.toString());
        JSONObject orderObject = null;
        try {
            orderObject = resultData.getJSONObject("Value");
        } catch (JSONException e) {
            //解析失败，很可能登陆失败、输出异常
            LoginInfo loginInfo2 = analyErrorResult(resultData);
            //再次下单
            logger.info("今朝阳下单接口，很可能登陆失败、刷新登陆信息后、再次下单："+lgsOrder);
            result = jSaveDocument(loginInfo2,lgsOrder,cargoValue,packageP,bigDecimal);
            resultData = new JSONObject(result);
            logger.info("今朝阳再次下单接口，返回结果："+resultData.toString());
            orderObject = resultData.getJSONObject("Value");
        }
        String lgsTrackNumber = orderObject.getString("Indenture");
        logger.info("返回结果,运单号 lgsTrackNumber："+lgsTrackNumber);
        //logger.info("返回结果,运单号："+result);
        if (StringUtils.isEmpty(result)) {
            throw new WebServiceException("JZY login service is not available! 今朝阳服务接口调用出错! 返回结果为空");
        } else {
            orderBindUpdate.setId(lgsOrder.getId());
            orderBindUpdate.setLgs_track_number(lgsTrackNumber);
            logger.info("调用今朝阳下单接口成功，自动绑定运单："+orderBindUpdate);
             //保存成功订单号到redis缓存25小时
            try {
                redisTemplateStatic.opsForValue().set(BdConstant.LGS_ALREADY_SUCCESS_SAVE_ORDER_ID+lgsOrder.getId(),lgsTrackNumber,25, TimeUnit.HOURS);
                logger.info("保存物流订单号到缓存成功："+orderBindUpdate);
            } catch (Exception e) {
                logger.warn("下单到今朝阳成功，保存物流订单号到缓存失败:"+orderBindUpdate,e);
            }
            return orderBindUpdate;
        }
    }

    private static String jSaveDocument(LoginInfo loginInfo,LgsOrder lgsOrder,int cargoValue,int packageP,BigDecimal bigDecimal){
        return soap.jSaveDocument(
                loginInfo.getSessionId(),loginInfo.getUserId(),loginInfo.clientName,0,""
                ,"",Optional.ofNullable(lgsOrder.getTransport_mode_nm()).orElse(""),Optional.ofNullable(lgsOrder.getConsignee()).orElse(""),Optional.ofNullable(lgsOrder.getConsignee_address()).orElse(""),Optional.ofNullable(lgsOrder.getConsignee_phone()).orElse("")
                ,StringUtils.substring(Optional.ofNullable(lgsOrder.getGoods_name()).orElse(""),0,10)
                ,cargoValue,packageP,bigDecimal,bigDecimal
                ,true,false,true,false,false
                ,"挂账月结",Optional.ofNullable(lgsOrder.getProduct_size()).orElse(""),""
        );
    }

    private static int getStrToInt(String str){
        try {
            return Integer.parseInt(Optional.ofNullable(str).orElse("0"));
        } catch (NumberFormatException e) {
            e.printStackTrace();
            return 0;
        }
    }

    public static void main(String[] args) throws Exception {
        String lNumber = "0980396";
        List<String> traceNumbers = new ArrayList();


        //traceNumbers.add("0987976");
        traceNumbers.add("0988528");
       // traceNumbers.add("0987976");
       // traceNumbers.add("0987516");
        //traceNumbers.add("0987476");


//        traceNumbers.add("0980396");
//        traceNumbers.add("0980116");
//        traceNumbers.add("0979591");
        Map<String, List<TraceData>> map = batchQueryTraceData(login(), traceNumbers);
        Iterator var4 = map.keySet().iterator();

        while(var4.hasNext()) {
            String key = (String)var4.next();
            List<TraceData> tdList = (List)map.get(key);
            if(tdList==null||tdList.isEmpty())
                continue;
            //List<TraceData> sortList = tdList.stream().sorted(Comparator.comparing(TraceData::getTraceTime).reversed()).collect(Collectors.toList()); //根据时间排序
            //List<TraceData> sortList = tdList.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
            //System.out.println(sortList);
//            Iterator var7 = tdList.iterator();
//
//            while(var7.hasNext()) {
//                TraceData td = (TraceData)var7.next();
//                System.out.println(td);
//            }

            System.out.println("*********************");
        }

    }

    static {
        soap = service.getLogisticsServiceSoap();
    }

    @Value("${api.jzy.login.name}")
    public void setApiJzyLoginName(String apiJzyLoginName) {
        this.apiJzyLoginName = apiJzyLoginName;
    }

    @Value("${api.jzy.login.password}")
    public void setApiJzyLoginPassword(String apiJzyLoginPassword) {
        this.apiJzyLoginPassword = apiJzyLoginPassword;
    }

}
